package logview;

import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.Set;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import logview.mbeans.LogFile;

public class ViewServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static transient final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(ViewServlet.class);
	private MBeanServer server;
	
	@SuppressWarnings("unchecked")
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		final String uri = req.getRequestURI();
		final String key = req.getRequestURI().substring(uri.lastIndexOf('/')+1, uri.lastIndexOf('.'));
		
		log.debug("id: "+key);
		try {
			ObjectName on = ObjectName.getInstance(InitServlet.DOMAIN+":id="+key+",type="+LogFile.class.getName());
			Set mbeans = server.queryMBeans(on, null);
			if (mbeans!=null && mbeans.size()==1) {
				ObjectInstance oi = (ObjectInstance) mbeans.iterator().next();
				String file = (String) server.getAttribute(oi.getObjectName(), "Filename");
				final PrintWriter w = resp.getWriter();
				resp.setContentType("text/plain");
				if (isMicrosoft(req.getHeader("User-Agent"))) {
					w.write("Don't use Microsoft browsers, they're buggy, a security risk, and not standards compliant\n");
					w.write("we need to write this for MS browsers for their' bugs\n");
				}
				sendLog(w, new FileReader(file)); 
			} else {
				throw new NoSuchElementException("MBean "+on+" not found");
			}
		} catch (Exception e) {
			throw new ServletException(e.toString());
		}
	}
	
	private boolean isMicrosoft(String header) {
		return header!=null && header.indexOf("MSIE")>=0;
	}

	private void sendLog(PrintWriter w, Reader reader) throws IOException {
		final LineNumberReader br = new LineNumberReader(reader);
		String l = null;
		while ((l = br.readLine())!=null) {
			w.write(br.getLineNumber()+": ");
			w.write(l);
			w.write("\n");
			w.flush();
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public void init(ServletConfig config) throws ServletException {
		ArrayList srv = MBeanServerFactory.findMBeanServer(InitServlet.agentId);
		if (srv!=null && srv.size()==1) {
			this.server = (MBeanServer) srv.get(0);
		}
		log.debug(ViewServlet.class.getName()+" initialized");
	}
	
	@Override
	public void destroy() {
		super.destroy();
		log.debug(ViewServlet.class.getName()+" destroyed");
	}
}
